<template>
    <div>
        <div v-for="(cmdInfo,idx) in cmdList" :key="idx">

            <div class="cmditem " :class="runIdx==idx?'bgcolor-yellow':''">
                <span class="cmdidx" @dblclick="changeLevel($event,idx)" @contextmenu.prevent="changeLevel($event,idx)" 
                    title="左键双击修改为子命令,右键单击修改为父命令"
                    :class="cmdInfo.hideChild?'red':''"
                    @click="setChildShow(cmdInfo)"
                    >{{preIdx}}{{idx+1}}</span>
                <exSelect v-model="cmdInfo.type" label="" :dictList="typeList" size="mini" elstyle="width:110px;min-width:110px;margin-top:5px;"></exSelect>
                <i class="el-icon-caret-right" :class="runIdx==idx?'red':'blue'" title="执行当前指令" @click="runCmd(true,idx)" ></i>
                <i class="el-icon-top blue" title="上升" @click="movePos(idx,1)" ></i>
                <i class="el-icon-bottom blue" title="下降" @click="movePos(idx,0)" ></i>
                <i class="el-icon-plus blue" title="添加子命令" @click="addSubCmd(cmdInfo)" v-if="getSelCmd(cmdInfo).hasChild"></i>
                <el-tooltip placement="bottom" effect="light">
                    <div slot="content" style="padding:5px 10px;">
                        <el-link type="primary" @click="setByDevInfo(idx)" >自动填充</el-link><br/>
                        <el-link type="primary" @click="preView(idx)"  class="mt5">预览数据</el-link><br/>
                        <el-link type="primary" @click="delCmd(idx)"  class="mt5" >删除指令</el-link><br/>
                        
                        <el-link type="primary" @click="copyCmd(idx)"   class="mt5">复制指令</el-link><br/>
                        <el-link type="primary" @click="copyCmd(idx,true)"   class="mt5">复制指令文本</el-link><br/>
                        <div style="width:100%;border-bottom:1px dotted gray;height:1px;margin:5px"></div>
                        <exInput placeholder="指令内容" v-model="cmdStr" size="mini" width="100"></exInput><br/>
                        <el-link type="primary" @click="addCmd(idx)"   class="mt5">往前插入</el-link><br/>
                        <el-link type="primary" @click="addCmd(idx+1)"   class="mt5">往后插入</el-link><br/>
                        <el-link type="primary" @click="addCmd(idx,true)"   class="mt5">黏贴指令</el-link><br/>
                        <div style="width:100%;border-bottom:1px dotted gray;height:1px;margin:5px 0"></div>
                        <el-link type="primary" @click="movePos(idx,2)"   class="mt5">指令置顶</el-link><br/>
                        <el-link type="primary" @click="movePos(idx,3)"   class="mt5">指令置底</el-link><br/>
                        <el-link type="primary" v-if="getSelCmd(cmdInfo).hasChild" @click="reverseChild(cmdInfo)"   class="mt5">子命令逆序</el-link><br/>
                    </div>
                    <i class="el-icon-menu blue"></i>
                </el-tooltip>
                <component v-if="cmdInfo.type" :is="cmdInfo.type+'Cmp'" :ref="'comEl'+idx" :cmdInfo="cmdInfo" :devInfo="devInfo" :cmdIdx="idx" @stopRun="stopRun"></component>
            </div>
            <div v-if="!cmdInfo.hideChild && cmdInfo.children && cmdInfo.children.length>0" class="pl5">
                <cmdList :ref="'cmdList'+idx" :cmdList="cmdInfo.children" :devInfo="devInfo" :preIdx="(preIdx+'')+(idx+1)+'.'"
                     :pIdx="idx" @insertCmd="insertCmd" @runNextCmd="runNextCmd" @changeRunStatus="changeRunStatus"></cmdList>
            </div>
        </div>
    </div>
</template>


<script>

const allComponents = require.context('./cmd', false, /^.*Cmp\.vue$/)
let res_components = {}
allComponents.keys().forEach(fileName => {
  let comp = allComponents(fileName)
  res_components[fileName.replace("./","").replace(".vue","")] = comp.default
})

export default {
    name: "cmdList",
    components: res_components,
    props: {
        cmdList: { type: Array, default: [] },
        devInfo:{ type: Object, default: {} },
        preIdx : {type: String, default:""},
        pIdx : {}
    },
    data() {
        // this.cmdInfo.level = this.cmdInfo.level || 0;
        // this.cmdInfo.appPath = this.cmdInfo.appPath || "";
        // this.cmdInfo.x1 = this.cmdInfo.x1 || 0;
        // this.cmdInfo.y1 = this.cmdInfo.y1 || 0;
        // this.cmdInfo.x2 = this.cmdInfo.x2 || 0;
        // this.cmdInfo.y2 = this.cmdInfo.y2 || 0;
        return {
            cmdStr : "",
            typeList:[
                {name:"单次点击",value:"click"},
                {name:"滑动",value:"move"},
                {name:"等待",value:"wait"},
                {name:"文本备注",value:"remark"},
                {name:"逻辑-if",value:"if",hasChild:true},
                {name:"逻辑-循环",value:"for",hasChild:true,isCircle:true},
                {name:"逻辑控制",value:"logic"},
                // {name:"逻辑-continue",value:"continue"},
                // {name:"逻辑-break",value:"break"},
                {name:"矩形内随机移动",value:"rect"},
                {name:"查找图形",value:"findRect",hasChild:true},
                {name:"系统功能",value:"key"},
                {name:"定时",value:"timer"},
                {name:"循环点击",value:"circle"},
                {name:"打开程序",value:"openApp"},
                {name:"关闭程序",value:"stopApp"},
            ],
            runIdx : -2,
        };
    },
    watch:{
        runIdx(newval){
            if(newval<0){
                this.$emit("changeRunStatus",false,this.pIdx)
            }else{
                this.$emit("changeRunStatus",true,this.pIdx)
            }
        }
    },
    computed:{
    },
    provide () {
      return {
        doNextCmd: this.runNextCmd,
        refreshList : this.refreshList
      }
    },
    inject: ["refreshList"],

    mounted() {
    },

    methods: {
        setChildShow(cmd){
            if(cmd.hideChild){
                cmd.hideChild = false;
            }else{
                cmd.hideChild = true;
            }
            setTimeout(()=>{
                this.refreshList();
            },300)
        },
        changeRunStatus(isRuning,idx){
            if(isRuning){
                this.runIdx = idx;
            }
        },
        getSelCmd(cmdInfo){
            var cmd = {};
            cmd = this.typeList.find((item)=>{return item.value==cmdInfo.type})
            return cmd||{};
        },
        changeLevel(e,idx){
            var isDown = e.button==0?true:false;
            if(idx==undefined) return;
            if(isDown){
                if(idx==0) return;
                var preCmd = this.cmdList[idx-1];
                var cmdBase = this.getSelCmd(preCmd);
                if(cmdBase.hasChild){
                    var curcmd = this.cmdList.splice(idx,1)[0];
                    preCmd.children.push(curcmd);
                }
            }else{
                if(!this.preIdx) return;
                var curcmd = this.cmdList.splice(idx,1)[0];
                this.$emit("insertCmd",this.pIdx,curcmd)
            }
            this.refreshList();
            
        },
        runCmd(isOnce,idx=0){
            var el = this.$refs["comEl"+idx];
            if(!el || !el[0]){
                return;
            }
            el = el[0]
            if(el.$el && el.$el.focus) el.$el.focus()
            if(isOnce){
                if(el.initCmd) el.initCmd()
            }
            if(this.runIdx==idx){
                if(el.stopCmd) el.stopCmd();
                this.stopCmd();
            }else{
                this.runIdx = idx;
                if(el.runCmd) el.runCmd(isOnce)
            }
        },
        runNextCmd(param={}){
            var preCmd = this.cmdList[this.runIdx] || {};
            var cmdItem = this.getSelCmd(preCmd);
            if(param.children && preCmd.children.length>0){
                if(this.$refs['cmdList'+this.runIdx]) this.$refs['cmdList'+this.runIdx][0].runCmd()
                return;
            }
            this.runIdx++;
            var nextcmd = this.cmdList[this.runIdx];
            if(param.return){
                this.runIdx=-2;
                this.runEnd(param)
                return;
            }else  if(param.pcontinue && cmdItem.isCircle && preCmd.children && preCmd.children.length>0){
                this.runIdx--; //重新执行for指令
            }else  if(param.finish){
            }else if(param.continue || param.break){
                if(cmdItem.isCircle){ //要回到for循环处理
                    if(param.continue){
                        this.runIdx--;
                    }else if(param.break){//不进循环,继续往下
                    }
                }else{ //往上寻找循环体
                    this.runIdx=-2;
                    this.runEnd(param)
                    return;
                }
            }
            
            if(this.runIdx<0){
                this.runEnd()
                return;
            }
            if(this.runIdx>=this.cmdList.length){
                this.runEnd()
                return;
            }
            if(nextcmd && !nextcmd.type){
                this.runNextCmd()
                return;
            }
            this.$refs["comEl"+this.runIdx][0].runCmd()
        },
        runEnd(param){
            param = param || {pcontinue:true};
            this.runIdx=-2;
            this.$emit("runNextCmd",param)
        },
        initCmd(){
            for(var i=0;i<this.cmdList.length;i++){
                try{
                    var el = this.$refs["comEl"+i];
                    if(el){
                        if(el[0].initCmd) el[0].initCmd()
                    }
                    var cmdel = this.$refs["cmdList"+i];
                    if(cmdel){
                        if(cmdel[0].initCmd) cmdel[0].initCmd()
                    }
                }catch(ex){

                }
            }
        },
        stopCmd(){
            this.runIdx=-2;
            if(this.cmdList.length==0) return;
            for(var i=0;i<this.cmdList.length;i++){
                try{
                    var el = this.$refs["comEl"+i];
                    if(el && el[0].stopCmd){
                        el[0].stopCmd()
                    }
                    var cmdel = this.$refs["cmdList"+i];
                    if(cmdel){
                        if(cmdel[0].stopCmd) cmdel[0].stopCmd()
                    }
                }catch(ex){

                }
            }
        },
        stopRun(){
            // this.isRuning = false;
        },
        delCmd(idx){
            this.cmdList.splice(idx,1)
            this.refreshList();
        },
        copyCmd(idx,isStr){
            var cmd = this.cmdList[idx];
            if(isStr){
                cmd = JSON.stringify(cmd);
                this.copy(cmd);
                this.cmdStr = cmd;
            }else{
                cmd = JSON.parse(JSON.stringify(cmd));
                this.cmdList.splice(idx,0,cmd)
                this.refreshList();
            }
        },
        preView(idx){
            if(this.$refs['comEl'+idx][0].preView) this.$refs['comEl'+idx][0].preView()
        },
        insertCmd(idx,cmd){
            this.cmdList.splice(idx+1,0,cmd)
        },
        setByDevInfo(idx){
            if(this.$refs['comEl'+idx][0].setByDevInfo) this.$refs['comEl'+idx][0].setByDevInfo()
        },
        getNewCmd(){
            return {type:"",children:[]}
        },
        addCmd(pos,isSelf){
            if(pos!==undefined){
                var cmd = null;
                try{
                    cmd = JSON.parse(this.cmdStr)
                }catch(ex){
                    cmd = this.getNewCmd();
                }
                if(isSelf){
                    this.cmdList.splice(pos,1,cmd)
                }else{
                    this.cmdList.splice(pos,0,cmd)
                }
            }else{
                this.cmdList.push(this.getNewCmd());
            }
            this.refreshList();
        },
        addSubCmd(cmdInfo){
            cmdInfo.children = cmdInfo.children || [];
            cmdInfo.children.push(this.getNewCmd());
        },
        reverseChild(cmdInfo){
            cmdInfo.children.reverse()
            this.refreshList();
        },
        movePos(idx,type){
            if(idx==0 && type==1) return;
            if(idx==this.cmdList.length-1 && type==0) return;
            var curcmd = this.cmdList.splice(idx,1)[0];
            if(type==2){ //置顶
                this.cmdList.splice(0,0,curcmd);
            }else if(type==3){ //置底
                this.cmdList.push(curcmd);
            }else if(type==0){ //下降
                this.cmdList.splice(idx+1,0,curcmd);
            }else{
                this.cmdList.splice(idx-1,0,curcmd);
            }
            this.refreshList();
        },
        saveCmd(){
            if(this.cmdList.length<=0) return;
            for(var i=0;i<this.cmdList.length;i++){
                try{
                    var el = this.$refs["comEl"+i];
                    if(el && el[0].saveCmd){
                        el[0].saveCmd()
                    }
                    var cmdel = this.$refs["cmdList"+i];
                    if(cmdel){
                        if(cmdel[0].saveCmd) cmdel[0].saveCmd()
                    }
                }catch(ex){

                }
            }
        },
    }
}
</script>

<style lang="less" scoped>
.cmditem{
    border-bottom: 1px gray dotted;
    padding-bottom: 5px;
    vertical-align: top;
    >i{
        margin-top: 10px;
        display: inline-block;
    }
    >.cmdidx{
        margin-top: 7px;
        display: inline-block;
    }
    *{
        vertical-align: top;
    }
}
</style>
<style>

</style>
